package com.mikufufu.blog.utils;

import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.*;

@Slf4j
public class IpUtil {

    /**
     * 从HttpServletRequest中获取客户端真实IP地址
     *
     * 方法按优先级尝试从多个代理服务器标准头字段中获取IP地址，处理多层代理和本地访问场景。
     * 注意：当存在多个IP时会截取第一个有效IP（按逗号分隔）
     *
     * @param request HTTP请求对象，用于获取请求头信息和远程地址
     * @return 处理后的客户端IP地址字符串（可能去除端口和多余代理信息）
     */
    public static String getIpAddress(HttpServletRequest request) {
        String ipAddress = request.getHeader("X-Real-IP");
        // 按优先级检查代理服务器头信息
        if (StringUtils.isBlank(ipAddress) || "unknown".equalsIgnoreCase(ipAddress)) {
            // 处理x-forwarded-for头信息,常用在Nginx代理服务器上
            ipAddress = request.getHeader("x-forwarded-for");
        }
        if (StringUtils.isBlank(ipAddress) || "unknown".equalsIgnoreCase(ipAddress)) {
            // 处理Proxy-Client-IP头信息,常用于Apache代理服务器上
            ipAddress = request.getHeader("Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ipAddress) || "unknown".equalsIgnoreCase(ipAddress)) {
            // 处理WL-Proxy-Client-IP头信息,常用于WebLogic代理服务器上
            ipAddress = request.getHeader("WL-Proxy-Client-IP");
        }
        if (StringUtils.isBlank(ipAddress) || "unknown".equalsIgnoreCase(ipAddress)) {
            // 处理HTTP_CLIENT_IP头信息,用于Apache代理服务器上
            ipAddress = request.getHeader("HTTP_CLIENT_IP");
        }
        if (StringUtils.isBlank(ipAddress) || "unknown".equalsIgnoreCase(ipAddress)) {
            // 处理HTTP_X_FORWARDED_FOR头信息,用于Nginx代理服务器上
            ipAddress = request.getHeader("HTTP_X_FORWARDED_FOR");
        }

        // 当所有代理头都不存在时，使用远程地址并处理本地访问场景
        if (StringUtils.isBlank(ipAddress) || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
            if ("127.0.0.1".equals(ipAddress) || "0:0:0:0:0:0:0:1".equals(ipAddress)) {
                // 处理本地回环地址，尝试获取本机实际网络IP
                InetAddress inet = null;
                try {
                    inet = InetAddress.getLocalHost();
                } catch (UnknownHostException e) {
                    log.error("getIpAddress exception:", e);
                }
                assert inet != null;
                ipAddress = inet.getHostAddress();
            }
        }

        // 处理可能存在的多个IP地址（如x-forwarded-for的多值情况）
        return StringUtils.substringBefore(ipAddress, ",");
    }

    /**
     * Ping 一个地址
     *
     * @param address （例：192.168.1.1 或 192.168.1.1:8080）
     */
    public static boolean ping(String address) throws Exception {
        if (address.contains(":")) {
            String host = address.split(":")[0];
            int port = Integer.parseInt(address.split(":")[1]);

            try (Socket socket = new Socket()) {
                SocketAddress addr = new InetSocketAddress(host, port);
                socket.connect(addr, 3000);
                return true;
            } catch (IOException e) {
                return false;
            }
        } else {
            return InetAddress.getByName(address).isReachable(3000);
        }
    }

    public static String getUserAgent(HttpServletRequest request) {
        return request.getHeader("User-Agent");
    }

}
